public class ReadMe {
    /**
     * 2022-12-6 数据库基础
     * 1.创建第四阶段项目
     * 2.数据库：
     *      1.下载安装数据库
     *      2.安装的时候，要输入用户名和密码：密码越简单越好123456
     *      3.重新装mysql的时候会出问题，服务无法安装
     *      4.怎么查看MySQL服务？
     *      5.安装MySQL的桌面工具？workbench，navcat sqlyoung
     * 3.在workbench里面连接数据
     * 4.创建数据库：
     * CREATE SCHEMA `canyin` ;
     * create database canyin2;
     * 5.删除数据库：DROP DATABASE `canyin2`;
     * 6.数据库包含：
     *      --  table  表  Java的对象
     * --   view  视图  Java集合 对多个对象里面的数据进行封装
     * -- stored procedure  存储过程  以后不用
     * -- function 方法，函数 自定义方法
     * 7.创建表:和Java里面的对象一一对应
     *          表名和Java的model里面的类名一致
     *          userModel={username='aa',password='bb'};
     *          user(username,password,sex);
     *          表示表数据唯一，一般用主键id;
     *          VARCHAR(45)  字符  45表示45个字符
     *          CHAR(45) 字符  也是表示45个字符？
     *
     * 8.既然mysql是一门语言，那么MySQL也应该有自己的语法结构
     *      1）数据类型
     *          int   int
     *          byte  TINYINT  状态  1已收货2已发货3已付款4退款5
     *          short  smallint
     *          long  bigint
     *          float
     *          double
     *          boolean  TINYINT
     *          char
     *          BigDecimal   decimal(m,n); m表示多少个有效数字，n表示多少位小数
     *          Object
     *      2）语法  if else  for
     *      3）数组集合，引用类型
     *      4）对象(表)
     *      --------------
     *      一个完整的JavaBean
     *      属性， 修饰符  数据类型  标识符
     *      方法，对应MySQL里面的函数 function
     *      构造
     *--------------------------------------------------
     * 9.数据库默认引擎是InnoDB和MyISAM的区别？
     * 10.MySQL有没有布尔数据类型？
     * 11.MySQL  TINYINT对应Java里面的byte
     * 12.VARCHAR 和CHAR的区别？和TEXT的区别?
     *      varchar  可变长字符串  45  最大保存45个字符   如果只有一个字符，则占用一个空间
     *      char  定长字符串       45  最大保存45个字符  如果只有一个字符，还是占用45个空间
     *      一般在字符串长度差不多一致的情况下用char  一般用于密码（因为密码会加密）
     *      一般  字符小于255的用char，在255到65535用varchar 多余65535用text
     * 13.TIMESTAMP和DATETIME的区别？
     *      TIMESTAMP  取值范围不一样
     *      DATETIME
     * 14.数据库的常用数据类型
     *      1）int            id  数据库一般一个表大于500万条或者大于2G都会进行分库分表
     *      2)tinyint         byte以内的数
     *      3）DATETIME       时间 1000-9999之内的时间
     *      4）TIMESTAMP      时间  1970-2038年之内的时间
     *      5）decimal        用于精确小数：价格
     *      6）char           定长数据
     *      7）varchar        不定长数据
     *      8）text           长文本
     *------------------------------------
     * 今日内容：
     *  1）建库
     *  2）数据类型
     *  3）建表
     *  CREATE TABLE `user` (
     *   `id` INT NOT NULL AUTO_INCREMENT,
     *   `name` VARCHAR(45) NULL COMMENT '用户账号',
     *   `password` CHAR(45) NULL,
     *   `sex` TINYINT NULL DEFAULT 1,
     *   `email` VARCHAR(45) NULL,
     *   `phone` VARCHAR(45) NULL,
     *   `address` VARCHAR(45) NULL,
     *   `weight` DECIMAL(5,2) NULL,
     *   `birthday` TIMESTAMP NULL DEFAULT '2022-2-22',
     *   PRIMARY KEY (`id`),
     *   UNIQUE INDEX `name_UNIQUE` (`name` ASC) VISIBLE)
     * ENGINE = InnoDB
     * COMMENT = '用户表';
     *
     */
    /**
     * 2022-12-7 定义语言和控制语言
     * 1.创建表关键字
     *      create  table  表名(
     *      列名 数据类型  是否为空  注释/默认值，
     *      列名  数据类型  是否为空 注释/默认值，
     *      primary key (id)
     *
     *      )
     * 2.修改表名：
     *      ALTER TABLE `user`
     *      RENAME TO  `usera` ;
     * 3.修改数据类型
     *      ALTER TABLE `user`
     *      CHANGE COLUMN `birthday` `birthdaya` DATETIME NULL DEFAULT '2022-02-22 00:00:00' ;
     * 4.添加一列
     *      ALTER TABLE `user`
     *      ADD COLUMN `create_time` DATETIME NULL DEFAULT now() AFTER `birthday`,
     * 5.删除表
     *      DROP TABLE `usera`;
     * 6.删除表数据
     *      TRUNCATE `usera`;
     * 7.新增数据
     *      INSERT INTO `user` (`name`, `password`, `sex`, `email`, `phone`, `address`, `weight`, `birthday`, `create_time`)
     *      VALUES ('aaa', 'aaaa', '1', 'a', 'a', 'a', '1', '2022-2-22', '2022-2-22');
     *      关键字：
     *      insert  into  表名(列名) values (值),(值)
     *      如果新增失败，还是会占用id的编号,
     * 8.修改数据
     *      UPDATE `user` SET `name` = 'ccc', `password` = 'ccc', `sex` = '3',
     *      `email` = 'c', `phone` = 'c', `address` = 'c', `weight` = '3',
     *      `birthday` = '1999-9-9', `create_time` = '2111-11-11'
     *      WHERE (`id` = '5');
     *      关键字：
     *      update 表名 set
     *      列名=值，
     *      列名=值
     *      where id=值
     * 9.删除数据：
     *      DELETE FROM `user` WHERE (`id` = '4');
     *      关键字：
     *      delete  from 表名
     *      where id=值
     * 10.DROP和TRUNCATE和DELETE的区别？
     *      drop 直接删除表
     *      truncate 删除表数据  id从0开始
     *      delete 删除表数据  id还在  可能还可以恢复数据
     * ------------------------------------------------------
     * 11.控制语言
     *      1.分配账号：
     *      2.分配权限：
     * 12.导出mysql里面的数据
     * 13.导入数据
     * ------------------------------------------
     * 14.创建表需要遵循三大范式
     *      1）原子性：列最小，不能再次拆分,
     *              如用户表里面的地址，可以有无数个，如果全写在一个表，那么会冗余，
     *              或者有些地址为空，则需要在创建一个地址表
     *              create table address(id,name);
     *              那么怎么和用户表进行关联：
     *              1）在地址表里面添加一个用户的id user_id；
     *              2）通过第三张表关联: id  address_id   user_id;
     *      2)唯一性：表不能包含其他表的属性，耦合度不能太大
     *      3）冗余性：一个表里面的数据不能太多一样。
     * 15.五大约束
     *      1）主键约束：必须要有主键  唯一性
     *      2）唯一约束  唯一性 用户名，用户id唯一，用户身份证唯一，
     *      3）默认值约束   整型more一个值，或者不允许数据库的列值为null
     *      4)非空约束
     *      5）设置外键约束  ：以后不用外键（外键一般是另一个表的主键）
     * --------------------------------------------------
     * 16.查询数据库：
     *      1）查询所有数据库show databases;
     *      2）查询当前数据库的所有表：show tables;
     *      3）查询当前表的所有数据：SELECT * FROM user;
     *      条件查询：where
     *      1.算术运算符
     *          select *,normal_price+price temp from product
     *      2.别名
     *          select *,normal_price+price as temp from product
     *      3.查询id大于多少的数据
     *          select * from product where id>50
     *      4.逻辑运算符
     *          select * from product where id>50 and id<70;
     *      5.between and
     *          select * from product where id between 50 and 70;
     *          select * from product where id>=50 and id<=70;
     *      6.not in
     *          select * from product where id  in(7,3);
     *          select * from product where id not in(7,3);遍历整个表
     *      7.模糊查询
     *          select * from product  where name like '%肉%';
     *          select * from product  where name like '%肉%' or name like '%回%';
     *          select * from product  where name like '%肉%' and name like '%回%';
     *          select * from product  where (name like '%肉%' or name like '%回%') and is_show=1;
     *      8.排序
     *          select * from product  order by id desc;降序
     *          select * from product  order by id asc;升序（默认升序）
     *      9.分组
     *          select where_show from product group by where_show,price;
     *          group by后面的列必须大于等于 select 后面的列
     *
     *
     */
    /**
     * 2022-12-8 数据库查询
     * 1.创建表的时候。列名应该和Model里面的属性一一对应，包括数据类型
     * 2.在数据库里面的列，还应该每个班都有一些共同的列：
     *      1）id  主键
     *      2）create_time  创建时间
     *      3）update_time  更新时间
     *      4）remark       备注
     *      5）enable       状态：启用，停用，注销等
     * 3.主键：目的，就是为了查询效率更高：最好自动自增（以后你新增数据的时候不用管主键的值）
     * 4.InnoDB，MySIAM引擎：存储引擎？
     *      将存储引擎理解为存储的方式不一样？
     *      MySIAM 一般查询快，新增和修改慢，而且一般不用于大量数据，兼容性好   5.5之前
     *      InnoDB 比MySIAM稍微慢，同时新增和修改快，可以用于范围的数据
     *      支持事务？原子性：要么成功要么失败
     *      InnoDB支持行锁？MySIAM支持表锁？
     *      MySIAM不支持外键
     * 5.主键：索引？目的？
     * -------------------------------------------
     * 6.分页公式
     *      -- 分页公式  select * from product limit （page-1）*size,size  page第几页，size每页显示多少条  size=12  page=3
     *      --  limit 不支持运算符，只能写结果
     *      -- limit （page-1）*size,size
     *      -- limit  start,size   limit 2,3
     *      select * from product limit start,size;
     *      所以，如果想要查询分页最主要的是得到第几页和每一页显示的条数即可
     *      分页的代码写在sql语句的最后面
     * 7.总条数
     *      select count(*) as count from product;
     *      count(*) 和count(1) 和count(id) 区别？
     *      count(*)默认找索引的总条数
     * 8.日期格式化
     *      select  DATE_FORMAT(NOW(),'%Y/%m/%d') birthday;
     * 9.表与表之间的关系？对象与对象之间的关系？
     *          产品   菜系  多对一
     *          回锅肉   川菜
     *          青椒肉丝  川菜
     *          ----------------- 一对一关系
     *          一个人    一张身份证
     *          --------------- 一对多 关系
     *          一个新闻类型 对应多条新闻
     *          --------------- 多对多关系
     *          一个学生对应多个老师
     *          一个老师对应多个学生
     *  ---------------------------------------------
     * 10.将产品和菜系进行连接：找到产品对应的菜系
     *      select * from product ,cuisine
     *      where product.cuisine_id=cuisine.id;
     *      对表名别名
     *      select * from product p,cuisine  c
     *      where p.cuisine_id=c.id
     * 11.内连接 ：两两连接
     *      select * from product p
     *      inner join
     *      cuisine  c
     *      on p.cuisine_id=c.id
     * 12.左连接：以左边表为为基准，将左边表都查询出来，
     *      右边表如果没有对应的数据则用null显示
     *      select * from product p
     *      left join
     *      cuisine  c
     *      on p.cuisine_id=c.id
     * 13.右连接：以右边表为基准，将右边表的所有数据进行查询，
     *      左边表如果没有对应的数据则显示null
     *      select * from product p
     *      right join
     *      cuisine  c
     *      on p.cuisine_id=c.id
     * 14.合并查询
     *      select * from product where id=(select max(id) from product where id<66)
     *      union all
     *      select * from product where id=66
     *      union all
     *      select * from product where id=(select min(id) from product where id>66);
     *      --   union all  表示不去重复的数据
     *      -- union  去掉重复的数据
     *      select * from product where id in(66,(select max(id) from product where id<66),(select min(id) from product where id>66));
     * 15.mysql 代码的书写顺序
     *      select -->from-->where -->group by-->having-->order by -->limit
     *
     *      1）首先查询所有数据，然后根据where条件进行比较，所以回遍历整个表
     *      2）如果想要查询更快，最好加索引条件：id>500
     *
     * 16.having  对排序进行条件查询（排序后的数据进行条件查询）
     *      select where_show from product  group by where_show having  where_show>=3
     * 17:MySQL 总结
     *      1）表名，字段名 全用小写英文
     *      2）表名 不要使用复数
     *      3）不要使用关键字
     *      4）列名 不要加pk_id,也不要加表名  product_name,product_price
     *      5)小数全部为decimal，禁止使用float和double
     *      6）char 用于固定字符串长度
     *      7）超过5000的长度就用text文本
     *      8）表必备字段：id，create_time，update_time，enable，remark；
     *      9）根据数据的内容确定数据类型
     *
     *
     */
    /**
     * 2022-12-9 Java连接数据库
     * 1.置顶2条推荐2条剩余的普通
     * (select * from product where enable=1  limit 2)
     *  union all
     * (select * from product where enable=2  limit 2)
     * union all
     * (select * from product where enable=3  limit 4)
     * 2.如果置顶只有一条，推荐1条，那么怎么办？
     *      1）分三次去查询，将每次查询的结果放入集合，
     *      2）如果指定只有1条，推荐只有一条，那么普通就是6条
     *          //list存放查询后的所有数据，用于展示到页面
     *          List<ProductModel> list=new ArrayList<>();
     *          //在数据库里面查询置顶的数据
     *          //select * from product where enable=1  limit (page-1)*size,size;
     *          List<ProductModel> listTop=new ArrayList<>();
     *          //将置顶的数据存入list
     *          list.add(listTop);
     *          //查询推荐的数据
     *          // select * from product where enable=2  limit (page-1)*size,size;
     *          List<ProductModel> listRecommend=new ArrayList<>();
     *          // 将推荐数据存入list
     *          list.add(listRecommend);
     *          // 根据list的长度，查询剩余的普通的条数
     *          // select * from product where enable=3  limit (page-1)*(8-list.size),(8-list.size);
     *          List<ProductModel> listNormal=new ArrayList<>();
     *----------------------------------------------------
     * Java是存放到服务器的，尽量不要写太多的逻辑关系
     * 能够在数据库里面操作的就不要在Java里面来
     * 能够在前端写的逻辑就不要写在Java里面来
     * -----------------------------------------------------
     * 前端--后台--数据库逻辑关系
     * 1.前端提交数据到Java后台的servlet
     * 2.在Java后台servlet里面做了六大步骤
     * 3.在service层里面写逻辑关系
     * 4.在dao层里面封装数据  :写sql语句和调用工具类
     * 5.dao层里面的数据应该来源于数据库（今日内容）
     * --------------------------------------
     * 1.servlet 里面的方法 一般情况下 更新用post，查询用get
     * 2.以后只要有数字转换的时候，都要判断是否能正确转换
     * 3.普通父类：相同属性和相同方法
     *   抽象父类：相同的属性和相同的方法，只不过有些方法不需要实现
     *   接口父类：如果都是抽象方法，则提供接口
     * 4.servlet里面service的接口命名规则
     *    1)一般情况下 接口命名规则：以I开头
     *    2）其他情况下根据项目来定，如service：类+Service，如dao：类+Dao
     *    3)实现层：UserServiceImpl  dao  UserImpl(UserDaoImpl)
     * 5.返回给前端（从第四阶段开始）：没有jsp页面
     *      所以给前端具体数据：
     *      以后基本上前后端传值都是通过对象进行传值
     *      Java怎么将数据强制转换为对象呢？
     *      可以通过第三方工具进行封装 fastjson
     * 6.密码加密：jdk自带的MD5
     * 7.JDBC的书写步骤
     *      1）引用jar包
     *      2）jdbc的步骤
     *          1）加载驱动
     *          2)得到连接
     *              jdbc:mysql:// 固定的
     *              121.199.55.96: 地址
     *              3306/ 端口
     *              canyin04? 数据库名称
     *              serverTimezone=UTC&  时区
     *              characterEncoding=UTF-8  处理乱码
     *       3)编译sql
     *       4）执行sql
     *       5）返回影响的值
     *       6）关闭连接
     * --------------------------------------------------------
     * 新增的步骤：
     *  1）servlet  六大步骤
     *  2）service  逻辑编写 调用dao层
     *  3）dao   sql语句和调用工具类JDBC
     *  4）JDBC 需要修改URL，USER,PASSWORD
     */
    /**
     * 2022-12-12 用户更新
     * 更新步骤：
     *      1.servlet  六大步骤
     *      2.调用service
     *      3.dao
     *      5.JDBC
     *      难点：
     *      1）servlet 封装model
     *      2）sql语句   要判断是否为空等操作
     *      3）最后有逗号怎么解决
     *
     * 1.修改密码需要单独设置
     * 2.删除：
     * 3.查询一条数据的时候，必备条件就是id
     * 4.根据分页去查询
     * 5.每次跟新model的时候，都会重新设置set和get方法，比较麻烦，所以有没有自动生成set和get方法的插件呢？
     *      lombok插件
     * 6.sql语句每个单词前后都记得加空格
     * ------------------------------
     * 今日任务：
     *  1.将后台代码  servlet，service  ，dao的代码写完（不包括sql语句）
     *  2.写sql语句  （难点）
     *
     */
    /**
     * 2022-12-13 产品CRUD 文件上传
     * 新增
     *      1.model   和数据库的产品表 的列名一一对应
     *      2.servlet    前端想要传递什么数据给后台（数据库想要保存什么数据）
     *          1）乱码处理
     *          2)得到前端的数据
     *          3)
     *          4)
     *          5)
     *          6)
     *      3.service 逻辑服务处  处理逻辑和调用dao层
     *      4.dao   写sql语句，调用JDBC的更新/查询
     * ---------------------------------------------------------
     * 文件上传：
     *      1.引入jar包
     *      2.FileUploadServlet
     *          1)判断是否为文件，如果不是则直接return
     *          2）将前端传递的文件通过强制转换成Java的List<FileItem></FileItem>
     *          3)遍历文件内容，然后将文件拷贝
     *      3.返回一个地址
     * ------------------------------
     *
     */
    /**
     * 2022-12-14  引入mybatis
     * 新增：
     *      1：model  和数据库的列名一一对应，多几个区间查询
     *      2：servlet 页面控制层   这里面不能存在逻辑关系 ：这里只做解析前端数据和封装完后将数据返回前端
     *      3：service 服务逻辑层  写逻辑代码的地方
     *      4：dao   数据持久层   和数据库打交道
     *      5：JDBC  调用数据库  和数据库打交道
     * ----------------------------------------------
     * 难点：  sql语句
     * 注意：
     *      1：servlet  需要判断前端传递过来的值是否正确
     *      2：servlet   需要将返回的数据封装为json对象：因为以后前后端传值的所有数据传输都是JSON对象
     *      3：service  密码处理，验证码处理
     *      4：dao   sql语句：怎么拼接sql语句
     * ------------------------------------------
     * 如果不控制用户输入的数据，则会出现sql注入的风险
     * 所以，以前的这种sql语句不好，你们需要了解sql注入的风险有哪些？
     * 怎么控制sql注入？
     * java代码用？进行参数传递，怎么对？进行赋值？
     * 如果用JDBC防止sql注入？
     *      1）将所有的参数用？代替
     *      2）将所有的数据存入到一个list
     *      3）在JDBC里面用for循环将所有数据传入sql语句进行执行
     *-----------------------------------------------
     * 因为做模糊查询的时候，每次都要用？，而且是自己手写，
     * 我们就要想到有没有别人已经开发好的代码，帮我们做？
     * mybatis 第三方
     *      1）引入mybatis包
     *      2）连接数据库？配置文件mybatis-config.xml
     *          1：加载JDBC的资源文件jdbc.properties
     *          2：打印sql语句到控制台
     *          3：配置数据库连接池:优化了连接和关闭的性能
     *          4：设置映射关系，dao层怎么去连接我的sql语句
     *     3）Java怎么找到sql语句？
     *          1：读取mybatis-config.xml
     *          2：通过SqlSession去操作增删改查
     * mapper.xml 里面注意事项
     * 1.#{name}和${name}的区别？${name}会sql注入
     * 2.数据库的列和model里面的属性如果不一致，则查询不出来，需要命名别名
     * 3.返回值类型：
     *      resultMap="model"
     *      <resultMap id="model" type="com.wanxi.model.UserModel">
     * 4.以后不要用* 代替所有，而是想要什么查询什么
     *       <sql id="aa">
     *       <include refid="aa"></include>
     * 新增用户：
     *      1.引入mybatis包
     *      2.配置mybatis-config.xml
     *      3.导入：jdbc.properties
     *      4：导入GetSqlSession：封装了所有的sql语句操作，等同于以前的JDBC
     *      5：修改dao层： return GetSqlSession.getSqlSession().selectList("UserDao.findAll", model);
     *      6：在UserMapper.xml写sql语句
     *      7:如果是新的对象，则会在mybatis-config.xml添加一个mapper映射 <mapper resource="/mapper/UserMapper.xml"/>
     * 修改：
     *      5.修改dao
     *      6.在UserMapper.xml写sql语句
     * 删除：
     *      5.修改dao
     *      6：添加sql
     *-------------------------------------------
     * 今日任务：
     *  1：修改为mybatis
     *  2：能够通过postman进行正常的增删查改
     *
     */
    /**
     * 2022-12-15 菜系的新增
     * 菜系的新增
     *      1：model
     *      2：servlet
     *      3:service
     *      4:dao
     *------------------------------
     * 修改：只修改状态
     * 只需要一个id即可，
     * update product set   enable=1 where id=5;
     * String sql="UPDATE  product  SET enable = CASE enable WHEN 0 THEN 1 WHEN 1 THEN 0 END WHERE id="+productModel.getId();
     * String sql = "UPDATE  product  SET enable = 1-enable WHERE id = " + productModel.getId();
     * String sql = "UPDATE  product  SET enable=enable^1 where id=" + productModel.getId();
     * --------------------------------------------------------
     * 对于前端来说，我们应该返回一个统一的格式，让别人好理解
     * layui
     * {
     *   "code": 0,
     *   "msg": "",
     *   "count": 1000,
     *   "data": [{}, {}]
     * }
     * servlet 只做两件事情：得到前端的值，返回数据前端：不要做任何逻辑关系
     * -------------------------------------
     * 对于service和dao都封装了一个基类
     * 对于service 做了一个统一的返回值数据格式
     * --------------------------------------
     * 今日课程内容：
     * 1：菜系的新增 （JDBC）
     * 2：dao层的基类
     * 3:enable的修改的几种方式
     * 4：service的基类
     * 5：统一返回给前端的数据格式
     * -----------------------------------
     * 明天的内容：
     * 1：将返回的结果进行优化
     * 2：结束后台管理系统的Java代码
     * 下一个星期将前端的js
     *
     */
    /**
     * 2022-12-16 ResultModel的封装
     * 1.把公共的代码提取出来
     * 2.因为里面有四个参数，很多时候我们不需要直接传递4个参数
     * 3.所以，我们写了很多方法进行重载
     * 4.最终调用了一个方法，进行返回所有值的对象
     * 5.我们可以直接用全参数的构造方法
     * 6.查询所有和查询总条数的查询条件一致，所以应该将查询条件写在一起
     * 7.做一个查询条件的sql语句的拼接
     * 8.查询所有和根据id查询后都要封装到list，根据id查询list里面最多只有一条数据
     *--------------------------------------------------------
     * Java第四阶段后台代码逻辑梳理
     * 1.servlet  六大步骤
     * 2.service  逻辑处理：统一返回ResultModel
     * 3.dao    老老实实写sql语句：
     *          1：将查询所有和查询总条数的where条件进行封装private String getWhereSql(UserModel model) {
     *          2：将查询所有就和根据id查询得到的结果进行封装 private List<UserModel> getUserData(ResultSet query) {
     * 4.ResultModel里面的封装需要掌握：
     *
     */
    /**
     * 2022-12-19 JavaScript基础
     * 要开发后台管理系统：是不是应该自己写一个系统？
     *      我们可以拿别人写好的模板进行二次开发
     *      layui框架   xadmin模板
     *      最好不要去修改别人已经写好的代码
     *      所以自己如果要新增或者修改其他功能，最好是另外写代码
     * -----------------------------
     * 1.熟悉里面的代码
     * 2.修改样式和js的路径为绝对路径
     * 3.熟悉form表单，然后通过点击里面的按钮，将所有的数据提交到后台
     * 4.因为第四阶段不需要做页面转发和重定向，所以，不能直接通过form表单进行提交
     * 5.因为这里提交，会返回数据，直接返回给页面，而不能进行其他操作
     * 6.需要通过js来进行操作：
     * 7.因为html页面不要直接写js代码，所以应该将js提取出去
     * -------------------------------------------------------
     * 8.javascript 是一门编程语言：和Java差不多：sql 语言
     *    Java基础                                    javascript基础
     *    常量    static final NAME="aaa";            const NAME="AAA";
     *    变量    int a=11;                           let age=19;
     *    标识符
     *    数据类型  基本数据类型和引用数据类型，           js怎么来判断数据类型？五个数据类型
     *                                               字符，数字，布尔，对象，数组
     *     int [] arr={1,32,4};                      let arr = [num, str, boo, obj]
     *    运算符                                       同Java
     *    if  else switch                               同Java
     *    for  forEach                                  同Java
     *    while                                         同Java
     *    do while                                      同Java
     *    int[] arr={1,2,4}
     *    public int getAge(String name){               function methodName(parmName){ return 11;}
     *        return 11;
     *    }
     *  Student student=  new Student("张三",18);
     *  String aa="aa";里面包含很多方法                    同Java
     *  substring(1,5),substring(3)
     *  replace(oldStr,newStr);
     *  split("aa");
     *  length();
     *  trim();
     *  集合  List list=new ArrayList();                  同Java（数组）
     *  -----------------------------------------------
     *  前端页面怎么将数据传输到Java后台：ajax
     * 登录：逻辑业务逻辑
     *  1：编写登录页面
     *  2：用户输入用户名和密码
     *  3：点击登录按钮，得到用户信息，通过ajax将数据传递给Java后台
     *  4：得到后台传递到前端的数据：
     *      Java：
     *          1：servlet 六大步骤
     *          2：service 写逻辑关系:注意加密
     *          3：dao  根据用户名和密码查询，如果没有，则返回null，如果有，则返回新的对象
     *      web：
     *          1.根据res得到的值进行逻辑判断
     *          2.如果得到的1.则跳转到管理页面
     *          3.如果是0，则继续输入用户名和密码
     *-----------------------------------------------------------------
     * 总结：
     *      1.js的相关知识点
     *          1）数据类型 五个数据类型 数据定义
     *          2）方法定义
     *      2.layui相关知识点：
     *          1）layui.use('form', function ()  页面加载完成需要取得什么功能
     *          2）layer.msg('玩命卖萌中', function(){  layui自己的弹出提示
     *          3）form.on('submit(login)', function (data) { 监听按钮，点击提交
     *          4） return false;  不让页面刷新
     *          5）ajax  将前端的值传递到Java后台
     *          6）通过对res的结果进行逻辑处理
     *-------------------------------------------------
     * 今日任务：理清登录逻辑代码
     */
    /**
     * 2022-12-20 用户查询
     * 登录逻辑关系
     *      前端web：
     *          1）创建login.html页面
     *          2）引入js，得到form表单里面的值
     *              1：对div进行添加监听事件：  lay-submit lay-filter="login"
     *              2：点击时，对data进行重新赋值： data = data.field;
     *              3：禁止页面刷新：type="submit"会刷新页面，如果不想让他刷新
     *                  1.可以改成type="button"
     *                  2.可以将input改成div
     *                  3.直接在最后添加return false；
     *              4：通过ajax和后台关联：
     *                  $.ajax({
     *                      url: '/login',//对应Java后他的WebServlet注解里面的值
     *                      data: data,//要传递给后台的值，统一用json对象，不要转换为字符串
     *                      type: 'post',//对应Java后他的方法
     *                      dataType: 'json',//固定用法后面三种写法都是错的dateType/datetype/datatype
     *                      success: function (res) {//res就算Java传递给前端的值
     *                           console.log(res);
     *                      }
     *                  });
     *              5.根据返回的值，进行逻辑判断
     *                  if (res.count == 1) {
     *                         location.href = '/html/index.html'
     *                     } else {
     *                         layer.msg("登录失败，请重新尝试输入用户名或者密码");
     *                     }
     *      后端Java：1.servlet  2.service 3.dao
     * --------------------------------------------------------------
     * 1.欢迎页面，欢迎管理员登录，用户名的修改
     *      怎么获取到登录名？
     *      在前端怎么传递数据到另一个页面
     *      java后台怎么将值传递到另一个页面？作用域
     *      req.getSession.setAttribute(key,value);
     * 2.如果你们写代码的时候，感觉代码没有问题，但是值又不对，则需要清缓存，或者随时清缓存
     * 3.为什么有这个缓存，缓存的作用是什么？
     * 4.得到用户名后，怎么赋值给具体的div？
     * 5.css拿到div的几种方式吗？css选择器
     * 6.js 怎么拿到div？和css差不多，只是一般情况下，css用class，js用id
     * 7.$("#loginName").html(username);//赋值
     * 8.对div赋值，我们用对象.html(value);
     * 9.对input 里面的type=text赋值；$("#id").val(值);
     * 10.java要得到2018-04-25 20:50:53时间？时间格式化
     * 11.js的日期格式化也需要一个单独的封装：直接用
     * 12.当前时间，表示秒表一直在动，在刷新,那么怎么让js每一秒刷新:js定时器
     * 13. setInterval(setSysDate, 1000); 第一个参数就是执行的方法，第二个参数就算时间
     * -----------------------------------------------------
     * 用户查询：
     *      1.创建查询页面member-list.html
     *      2.修改管理页面，只留下会员列表，修改地址 <a onclick="xadmin.add_tab('会员列表','/html/user/member-list.html',true)">
     *      3.找到layui镜像网站，找到数据表格
     *      4.复制相关的html和js代码
     *      5.修改 table.render({，里面的elem: '#table'和url
     *      6.修改cols
     *          1）field对应model里面的属性，注意大小写
     *          2）最后一列操作栏：
     *
     */
    /**
     * 2022-12-21 密码修改和删除
     * 1.模板：templet: function (d) {
     * 2.设置样式
     * 3.点击删除时，怎么找到当前表格的删除？
     *      1)通过table里面的lay-filter="test"
     *      2）通过lay-event="del"
     * 4.调用Ajax
     * 5.根据后台传递的信息写逻辑关系
     * 6.js无法直接传递json对象
     * 7.可不可以先将json对象转换为字符串？JSON.stringify(data)
     * 8.字符串转换为json对象？JSON.parse(user)
     * 9.编辑密码的流程：
     *      1）创建页面
     *      2）创建js文件
     *      3）点击查询页面的修改密码，弹出修改密码页面
     *      4）弹出页面之前需要将用户名和id传递到另一个页面
     *      5)将用户名显示在输入表单里面，同时不能修改 disabled="" readonly
     *      6）点击提交的时候，将旧密码和新密码同时得到，传递到Java后台
     *      7）Java后台先查询当前的旧密码是否正确，
     *          如果旧密码不正确，则不让她修改密码
     *          否则修改成功
     *      8)点击修改密码按钮之前需要判断确认密码和新密码是否一致
     *      -------------------
     * 今日任务：
     *      将用户的删除和密码修改做完
     *      将其他对象表的删除做了
     */
    /**
     * 2022-12-22 用户新增
     * 每一个功能都应该有自己的流程图
     * 新增的逻辑梳理;
     *      1)创建新增页面 member-add.html
     *      2）判断用户输入的格式是否正确：product-add.js
     *      3)添加正则表达式进行验证form.verify({
     *      4）得到form表单里面的值，难点在复选框
     *      5)点击按钮将数据传递到Java后台
     *      ------------------------------------
     *
     */
    /**
     * 2022-12-23 重做前端返回值结果
     * 1.前端访问后台，那么后台是不是应该给前端一个反馈反应？
     * 2.前端主要是做增删查改的操作，
     *      对于数据库来说，
     *      增加删除修改返回的是1或者0；影响的条数  int
     *      对于查询：根据id查询，得到的是一条数据  model
     *      查询所有或者模糊查询，得到的是多条数据  list
     *      对于前端来说，如果返回的结果不固定，则会觉得太乱，
     *      所以固定一个返回结果，这个返回结果格式由谁来决定？前端；
     *      {
     *   "code": 0,
     *   "msg": "",
     *   "count": 1000,
     *   "data": [{}, {}]
     * }
     * 既然是这种结果，那么就要知道这种结果后端怎么才能得到？
     * 现在后台返回给前端的统一格式用CommonResult
     * -------------------------------------
     * CommonResult应该在那个地方进行封装呢？
     * 因为我任务，封装属于逻辑，既然数据逻辑，就应该在逻辑层：service层
     * 每一个service基本数都有增删改查等7个公有的方法，所以，写了一个CommonService
     * 然后统一返回CommonResult
     * 一般情况下，工具类不要用new关键字创建对象
     * 为了防止别人new这个对象，怎么办？
     */
    /**
     * 2023-1-4 产品查询
     * 1.修改index页面的导航:product-list.html
     * 2.修改product-list.html里面的js
     *      1)页面加载完成执行里面的代码
     *      2）加载layui的模板
     *      3)修改 table.render({里面的 elem: '#table'
     *      4）修改url：'/back/product/findAll'
     *      5）修改：, cols: [[ //表头
     * -------------------------------------
     * Java后台：
     * 1：servlet：六大步骤
     * 2.service
     * 3.dao  sql语句
     *      1)查询所有
     *      2）查询总条数
     *      3)如果查询的时候加入了条件，应该是在查询的结果里面再去过滤
     *      4)sql子查询，将结果数据作为另一个查询的临时表
     *---------------------------------------------------------------
     *
     *
     */
    /**
     * 2023-1-5 产品图片和删除
     * 删除：
     *  1.点击删除时，找到对应的js
     *  2.删除数据，应该用sql语句删除， delete from product where id=138
     *  3.调用后台接口：/back/product/delete
     *  4.调用ajax，进行逻辑判断处理
     * 提取公共的ajax ：异步 async:false
     * --------------------------------
     * 查看：其实是对当前产品的预览：根据当前id查询数据并赋值到页面
     * 1.点击查看按钮，跳转到预览页面product-detail.html
     * 2.跳转之前，需要得到id，因为在详细页面需要查询产品描述信息
     * 3.当打开产品详细页面时，需要根据产品的id，去数据库查询数据
     * 4.查询数据后，将得到的数据赋值给当前页面
     */
    /**
     * 2023-1-6 产品新增
     * 1.点击新增按钮，弹出一个新增页面xadmin.open('添加产品','/html/product/product-add.html',600,400)
     * 2.创建product-add.html页面，复制表单元素
     * 3.复制增加按钮，并添加按钮的监听事件
     * 4.验证规则是否符合格式  form.verify({
     * 5.调用ajax访问后台（前提需要得到页面上的数据）
     * 6.根据后台返回的数据进行逻辑处理
     * ---------------------------------------
     * 在页面加载完成时，首先应该将菜系从数据库里面查询出来并赋值给下来菜单
     * --------------------------------------------------------
     *
     */
    /**
     * 2023-1-9 产品文件上传和富文本
     * 1.文件上传不能直接存到数据库
     *      1）文件太大，占用数据库的查询
     *      2）以后发布到服务器，数据库的成本会很大
     *      3）以后就算是文件很小，也应该将当前的列单独创建一个表。
     * 2.富文本上传
     *      1）导包wangEditor.js
     *      2）在html文件里面引入富文本js：<script src="/js/wangEditor.js"></script>
     *      3）在html代码里面添加富文本显示：<div id="content" style="height: 500px;width: 500px">
     *                     </div>
     *      4）在add.js里面添加创建富文本的代码:
     *          const E = window.wangEditor;
     *          ....
     *          editor.create();
     *      5）在点击添加按钮的时候，增加content的代码
     *          data.content=editor.txt.html();
     *      6）完成富文本
     * ----------------------------------------------------
     * 编辑产品：
     *      1）创建编辑产品的页面 product-update.html
     *      2)创建编辑产品的js：product-update.js
     *      3）思路：
     *          1）点击产品查询的编辑按钮，将当前的id传递到编辑页面
     *          sessionStorage.setItem("productId", data.id);
     *          2)弹出编辑页面
     *          xadmin.open('编辑产品', '/html/product/product-update.html', 600, 400)
     *          3)在编辑页面的js里面
     *              1）页面加载完成执行里面的代码 $(function(){})
     *              2)加载layui的模块：layui.use();
     *              3)加载文件上传和富文本编辑器的js
     *              3.5)需要先将菜系查询出来并赋值给页面
     *              4）得到查询页面的产品id
     *              5）根据产品页面查询的id查询数据库，并得到当前信息
     *              6）将当前信息进行赋值到页面
     *              7)点击编辑页面进行编辑（和增加按钮一样）
     *          4)添加编辑按钮的js，重点是需要传递一个id到后台
     *
     */
    /**
     * 2023-1-10 产品模糊查询
     * 思路：
     * sql语句： select * from product
     *  where name like '%aa%' and is_show=1 and price between 1 and 2
     *  order by id desc
     *  模糊条件查询 最重要的是将需要查询的数据从前端传递到后台,所以，直接在以前的findAll里面加条件即可
     * 1.我们应该加什么模糊查询的条件？
     *      根据客户在管理系统想要显示的数据进行查询
     * 2.java后台修改的地方：
     *      1)servlet  增加取得前端的值，和封装到model，如果model里面没有，则增加model的属性
     *      2）dao  增加模糊查询的条件：注意：findAll应该和count的查询条件一致
     * ---------------------------------------------------------
     * web端：
     *     1）对点击查询按钮进行监听:return false;
     *     2) 得到表单数据，然后table.render 进行渲染
     *     3）传递数据到后台： , where: data
     *     4）将两个table.render封装到一个方法，进行调用即可
     *----------------------------------------
     * 第四阶段任务：
     *      1：将所有表的增删查改做完CRUD
     *      2：用户，新闻，产品必须要有模糊查询，其他随便
     *      3：现在做的项目又哪些表：用户表，公司表，产品表，产品类型（菜系），新闻，新闻类型，留言表
     */
    /**
     * 2023-1-11 session安全认证  过滤器
     * 1.web端：正常情况下 用户不能直接访问某一个页面，必须登录才能进行访问
     *      1)用户没有登录的情况下，访问某个页面，则直接跳转到登录页面
     *      2）什么时候判断用户是否已经登录？
     *          在页面加载的时候就去判断（并不一定要页面加载完成）
     *          除了登录页面不需要判断用户是否已经登录，其他页面都需要判断，
     *          则判断用户登录的代码应该属于公共的代码:myAjax.js文件
     *      3）怎么判断用户没有登录？
     *          1)判断是否已经登录，可以设置一个标识，
     *          2）谁可以看到？所有页面，那么在所有页面都能够拿到那个标识
     *          3）那么应该将这个标识存在那个地方？sessionStorage
     *              java三大作用域
     *              request  请求页面
     *              session  会话期：tomcat启动 tomcat关闭  同一个浏览器（内存）
     *              application  应该程序： 跨浏览器：本地
     *              web 作用域
     *              sessionStorage
     *              localStorage
     *          4）什么时候存这个标识呢？登录成功以后
     *          5）在需要判断用户登录的地方，得到这个标识判断即可
     *          let username = sessionStorage.getItem("username");
     *          if (username == null) {
     *               window.location.href = "/html/login.html";
     *          }
     *
     * 2.Java端：正常情况下，用户不能直接访问后台的接口
     *          1)需要在访问后台接口之前对用户进行登录判断
     *          2）对哪些接口需要进行登录判断？除登录接口都要进行登录判断
     *          3）怎么标识用户是否已经登录？需要设定一个标识
     *          4）标识应该保存在那个地方？session
     *          5）什么时候设定标识？登录成功后
     *          6）代码编写
     *          7)MyFilter
     */

}
